package jflowmap.views.heatmap;

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Vector;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JPanel;

import jflowmap.FlowMapColorSchemes;
import jflowmap.data.ViewConfig;
import jflowmap.model.geo.MapProjection;
import jflowmap.model.graph.Graph;
import jflowmap.model.map.GeoMap;
import jflowmap.model.ontology.Context;
import jflowmap.model.ontology.Dimension;
import jflowmap.util.Comment;
import jflowmap.views.AbstractCanvasView;
import jflowmap.views.ColorCodes;
import jflowmap.views.MapBackgroundImage;
import jflowmap.views.VisualCanvas;
import jflowmap.views.flowmap.ColorSchemeAware;
import net.java.dev.designgridlayout.DesignGridLayout;
import edu.umd.cs.piccolo.PCanvas;
import edu.umd.cs.piccolo.util.PPaintContext;

public class HeatMapView extends AbstractCanvasView implements ActionListener {

	private VisualHeatMap heatMap;
	
	private final ViewConfig viewConfig;
	private final GeoMap areaMap;
	private final MapProjection projection;
	private final MapBackgroundImage mapImage;
	
	private final ColorSchemeAware mapColorScheme = new ColorSchemeAware() {
		@Override
		public Color getColor(ColorCodes code) {
			return FlowMapColorSchemes.LIGHT_BLUE__COLOR_BREWER.get(code);
		}
	};
	
	public ColorSchemeAware getMapColorScheme() {
		return mapColorScheme;
	}
	
	public HeatMapView(final String name, MapBackgroundImage mapImage, 
			GeoMap areaMap, MapProjection proj, ViewConfig config) {
		super(name);
		
		this.viewConfig = config;
		this.areaMap = areaMap;
		this.projection = proj;
		this.mapImage = mapImage;

		VisualCanvas canvas = getVisualCanvas();
		canvas.setInteractingRenderQuality(PPaintContext.HIGH_QUALITY_RENDERING);
		canvas.setAnimatingRenderQuality(PPaintContext.HIGH_QUALITY_RENDERING);
	}
	
	private void createVisualHeatMap (final Graph graph) {
		boolean firstTime = this.heatMap == null;
		
		if (!firstTime) {
			removeButtons(this.heatMap);
			this.heatMap.dispose();
		}
		setVisualHeatmap(new VisualHeatMap(this, graph, mapImage, projection, areaMap, this));
		addButtons(this.heatMap);
	}
	
	public VisualHeatMap getVisualHeatMap () {
		return this.heatMap;
	}
	
	public void setVisualHeatmap (final VisualHeatMap newHeatMap) {
		if (this.heatMap != null) {
			getVisualCanvas().getLayer().removeChild(this.heatMap);
			this.heatMap.removeNodesFromCamera();
		}
		
		getVisualCanvas().getLayer().addChild(newHeatMap);
		this.heatMap = newHeatMap;
		newHeatMap.addNodesToCamera();
	}
	
	private void removeButtons (final VisualHeatMap heatMap) {
		
	}
	
	private void addButtons (final VisualHeatMap heatMap) {
		
	}
	
	
	private JComboBox valueSelector;
	
	@Override
	public JComponent getControls() {		
		JComponent controls = new JPanel();
		DesignGridLayout content = new DesignGridLayout(controls);

		JButton update = new JButton("Aktualisieren");
		
		final Vector<String> values = new Vector<String>();
		for(Dimension dim: getView().require("VALUE")) {
			values.add(dim.getName());
		}
		
		valueSelector = new JComboBox(values.toArray());		
			
		content.row().left().add(valueSelector).add(update);

		update.setActionCommand("update");
		update.addActionListener(this);
		
		return controls;
	}
	
	@Override
	public void actionPerformed(ActionEvent event) {
		if ("update".equals(event.getActionCommand())) {
			
			final Context context = getView().getContext();
			
			final String graphName = getName() + " per " + (String) valueSelector.getSelectedItem();
			System.out.println("Viewing " + graphName);
			
			if (!context.existsGraph(graphName)) {
				context.defineGraph(graphName)
				.dimension(getView().require("SOURCE"))
				.asSource()
				
				.dimension(getView().require("TARGET"))
				.asTarget()
				
				.dimension(context.collect().anyChildOf().dimension((String) valueSelector.getSelectedItem()))
				.asValues();
			}
			
			createVisualHeatMap(context.getGraph(graphName));
		}
	}
	
	
	
	
	
	
	@Override
	public List<Comment> getComments() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public String getSpec() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public ViewConfig getViewConfig() {
		return this.viewConfig;
	}

	@Override
	public PCanvas startExport() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public PCanvas exportLegend() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void endExport() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public String getExportName() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void constrain(Map<String, Set<Dimension>> dimensions) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void update() {
		if (heatMap != null)
			heatMap.update();
	}

	@Override
	public WindowListener getWindowListener() {
		return new WindowAdapter() {
			@Override
			public void windowClosed(WindowEvent e) {
				if (heatMap != null)
					heatMap.dispose();
			}
		};
	}

	@Override
	public Graph getCurrentGraph() {
		return heatMap == null ? null : heatMap.getGraph();
	}
}
